package org.jfinanceobserver;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
import org.jfinanceobserver.persistence.ConnFactory;
import org.jfinanceobserver.persistence.jpa.controller.QuotesActiveJpaController;
import org.jfinanceobserver.persistence.jpa.controller.QuotesDataJpaController;
import org.jfinanceobserver.persistence.jpa.controller.exceptions.IllegalOrphanException;
import org.jfinanceobserver.persistence.jpa.controller.exceptions.NonexistentEntityException;
import org.jfinanceobserver.persistence.jpa.controller.exceptions.PreexistingEntityException;
import org.jfinanceobserver.persistence.jpa.entities.QuotesActive;
import org.jfinanceobserver.persistence.jpa.entities.QuotesData;
import org.jfinanceobserver.tmp.App;
import org.jfinanceobserver.utillities.AbstractDefaultTool;
import org.jfinanceobserver.utillities.CVSParser;

/**
 * This class insert an Active to be observed
 *
 * $Author: r78v10a07@gmail.com $ $LastChangedDate: 2013-02-11 14:03:43 +0100
 * (Mon, 11 Feb 2013) $ $LastChangedRevision: 20 $
 *
 * @since Feb 10, 2013
 */
public class HandleActive extends AbstractDefaultTool {

    private String add;
    private String del;
    private String act;
    private String off;
    private QuotesActiveJpaController aController;

    /**
     * Insert the Quotes on the string act
     *
     * @throws IOException
     */
    public void insert(String quotesSymbol) throws IOException, PreexistingEntityException, Exception {
        HashMap parm = new HashMap();
        System.out.println("Inserting quotes: " + quotesSymbol);
        try {
            URL oracle = new URL("http://download.finance.yahoo.com/d/quotes.csv?s=" + quotesSymbol + "&f=n0s0i0c4&ignore=.csv");
            URLConnection yc = oracle.openConnection();
            try (BufferedReader in = new BufferedReader(new InputStreamReader(yc.getInputStream()))) {
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    String[] values = CVSParser.parse(inputLine);
                    if (values.length == 4) {
                        parm.put("symbol", values[1]);
                        List<QuotesActive> actives = aController.useNamedQuery("QuotesActive.findBySymbol", parm);
                        if (!actives.isEmpty()) {
                            setActive(actives.get(0), true);
                        } else {
                            QuotesActive active = new QuotesActive();
                            active.setName(values[0]);
                            active.setSymbol(values[1]);
                            active.setInfo(values[2]);
                            active.setCurrency(values[3]);
                            active.setActive(true);
                            aController.create(active);
                        }
                    }
                }
            }
        } catch (MalformedURLException ex) {
            Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    /**
     * Remove the Quote on the string del
     *
     * @throws IllegalOrphanException
     * @throws NonexistentEntityException
     */
    public void remove() throws IllegalOrphanException, NonexistentEntityException {
        System.out.println("Removing quotes: " + del);
        QuotesDataJpaController dController = new QuotesDataJpaController(ConnFactory.getInstance().getFactory());
        HashMap parm = new HashMap();
        for (String q : getDel().split(",")) {
            parm.put("symbol", q);
            List<QuotesActive> actives = aController.useNamedQuery("QuotesActive.findBySymbol", parm);
            if (!actives.isEmpty()) {
                for (QuotesData data : actives.get(0).getQuotesDataCollection()) {
                    dController.destroy(data.getId());
                }
                actives.get(0).setQuotesDataCollection(null);
                aController.destroy(actives.get(0).getId());
            }
        }
    }

    /**
     * Deactivate the Quote on the string off
     *
     * @throws IllegalOrphanException
     * @throws NonexistentEntityException
     */
    public void deactivate(String quotesSymbols) throws IllegalOrphanException, NonexistentEntityException, Exception {
        System.out.println("Deactivating quotes: " + quotesSymbols);
        HashMap parm = new HashMap();
        for (String q : quotesSymbols.split(",")) {
            parm.put("symbol", q);
            List<QuotesActive> actives = aController.useNamedQuery("QuotesActive.findBySymbol", parm);
            if (!actives.isEmpty()) {
                setActive(actives.get(0), false);
            } else {
                insert(q);
                deactivate(q);
            }
        }
    }

    private void setActive(QuotesActive active, boolean activate) throws IllegalOrphanException, NonexistentEntityException, Exception {
        active.setActive(activate);
        aController.edit(active);
    }

    /**
     * Main class to handled the QuotesAtive table
     *
     * @param args the command line arguments (The string with the quotes
     * symbols to add)
     * @throws IOException
     * @throws IllegalOrphanException
     * @throws NonexistentEntityException
     */
    public static void main(String[] args) throws IOException, IllegalOrphanException, NonexistentEntityException, Exception {
        HandleActive active = new HandleActive();

        active.parseOptions(args);
        ConnFactory.getInstance().connect();
        active.setaController(new QuotesActiveJpaController(ConnFactory.getInstance().getFactory()));

        if (!active.getAdd().isEmpty()) {
            active.insert(active.getAdd());
        }
        if (!active.getAct().isEmpty()) {
            active.insert(active.getAct());
        }
        if (!active.getDel().isEmpty()) {
            active.remove();
        }
        if (!active.getOff().isEmpty()) {
            active.deactivate(active.getOff());
        }

        ConnFactory.getInstance().getFactory().close();
    }

    /**
     * Get the quotes to add
     *
     * @return the quotes to add
     */
    public String getAdd() {
        return add;
    }

    /**
     * Set the quotes to add
     *
     * @param add the quotes to add
     */
    public void setAdd(String add) {
        this.add = add;
    }

    /**
     * Get the quotes to remove
     *
     * @return the quotes to remove
     */
    public String getDel() {
        return del;
    }

    /**
     * Set the quotes to remove
     *
     * @param del the quotes to remove
     */
    public void setDel(String del) {
        this.del = del;
    }

    /**
     * Get the quotes to activate
     *
     * @return the quotes to activate
     */
    public String getAct() {
        return act;
    }

    /**
     * Set the quotes to activate
     *
     * @param act the quotes to activate
     */
    public void setAct(String act) {
        this.act = act;
    }

    /**
     * Get the quotes to deactivate
     *
     * @return the quotes to deactivate
     */
    public String getOff() {
        return off;
    }

    /**
     * Set the quotes to deactivate
     *
     * @param off the quotes to deactivate
     */
    public void setOff(String off) {
        this.off = off;
    }

    /**
     * Get the QuotesActiveJpaController
     *
     * @return the QuotesActiveJpaController
     */
    public QuotesActiveJpaController getaController() {
        return aController;
    }

    /**
     * Set the QuotesActiveJpaController
     *
     * @param aController the QuotesActiveJpaController
     */
    public void setaController(QuotesActiveJpaController aController) {
        this.aController = aController;
    }

    @Override
    protected void parseOptions(String[] args) throws FileNotFoundException {
        OptionParser parser = new OptionParser("a:d:o:f:");
        parser.accepts("a").withRequiredArg().ofType(String.class);
        parser.accepts("d").withRequiredArg().ofType(String.class);
        parser.accepts("o").withRequiredArg().ofType(String.class);
        parser.accepts("f").withRequiredArg().ofType(String.class);

        OptionSet options = parseDefaultOptions(parser, args, true);

        add = ((String) parseOption(options, "a", new String(), true, false));
        del = ((String) parseOption(options, "d", new String(), true, false));
        act = ((String) parseOption(options, "o", new String(), true, false));
        off = ((String) parseOption(options, "f", new String(), true, false));
    }

    @Override
    protected void printHelp() {
        System.out.println("Arguments:");
        System.out.println("\t-a Add quotes (format: \"GOOG,ORCL,AMZN,AAPL,FB,MSFT,AMD,YHOO,NVDA,INTC,DELL\")");
        System.out.println("\t-d Delete quotes (format: \"GOOG,ORCL,AMZN,AAPL,FB,MSFT,AMD,YHOO,NVDA,INTC,DELL\")");
        System.out.println("\t-o Active quotes (format: \"GOOG,ORCL,AMZN,AAPL,FB,MSFT,AMD,YHOO,NVDA,INTC,DELL\")");
        System.out.println("\t-f Desactive (format: \"GOOG,ORCL,AMZN,AAPL,FB,MSFT,AMD,YHOO,NVDA,INTC,DELL\")");
        System.out.println("");
        printDefaultHelp();
        System.exit(0);
    }
}
